﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Security.AccessControl;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using Telerik.OpenAccess;
using Telerik.OpenAccess.Diagnostics;
using vmModel;
using XenAPI;
using Aspose.Cells;

namespace ITMan
{
    public partial class FormVMList : Form
    {
        public FormVMList()
        {
            InitializeComponent();
        }

        IList<vmModel.Host> hostList= null;
        BindingSource vmBindingSource=new BindingSource();
        DataTable VMdt=new DataTable();
        
        
        private void InitHostGrid()
        {
            using (vmEntities dbContext= new vmEntities())
            {
                IQueryable<vmModel.Host> Hosts = from i in dbContext.Hosts
                                                 select i;
                var vms = from h in dbContext.Hosts
                          from v in dbContext.VMs
                          where h.Hostid == v.Hostid
                          orderby h.Ipv4
                          select new { HostIP = h.Ipv4, v.Ipv4, v.Ipv6, v.Vmname, v.State, v.Cpus, v.Memorys, v.Descr };
                if (Hosts.Any())
                    hostList = Hosts.ToList();

                if (vms.Any())
                {
                   
                    DataTable dt = new DataTable();
                    dt.Columns.Add("主机");
                    dt.Columns.Add("虚拟机IP");
                    //dt.Columns.Add("IPv6");
                    dt.Columns.Add("名称");
                    dt.Columns.Add("状态");
                    dt.Columns.Add("CPU");
                    dt.Columns.Add("内存");
                    dt.Columns.Add("描述");

                    foreach (var vm in vms)
                    {
                        DataRow dr = dt.NewRow();
                        dr["主机"] = vm.HostIP;
                        dr["虚拟机IP"] = vm.Ipv4;
                        //dr["IPv6"] = vm.Ipv6;
                        dr["名称"] = vm.Vmname;
                        dr["状态"] = vm.State;
                        dr["CPU"] = vm.Cpus;
                        dr["内存"] = vm.Memorys;
                        dr["描述"] = vm.Descr;
                        dt.Rows.Add(dr);
                    }
                    VMdt = dt; 
                    vmBindingSource.DataSource = VMdt;
                }
                else
                {
                    vmBindingSource.Clear();
                    VMdt = null;
                }
            }
        }

        public static bool VmIsExists(string uuid)
        {
            using (vmEntities dbContext = new vmEntities())
            {
                IQueryable<vmModel.VM> vms = from i in dbContext.VMs
                                             where i.Uuid == uuid
                                             select i;
                if (vms.Any())
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

        }

        private void FormVMList_Load(object sender, EventArgs e)
        {
            //test t= new test();
            //t.MethodA();

            InitHostGrid();
            dataGridViewHosts.DataSource = hostList;
            dataGridViewVMs.DataSource = vmBindingSource;
            tsStatusLabel.Text = string.Format("虚拟机数:{0}",vmBindingSource.Count);
            Refresh();
        }

        private void btVmGet_Click(object sender, EventArgs e)
        {
            int count = hostList.Count;

            //WaitHandle[] flags = new AutoResetEvent[count];
            //for (int i = 0; i < count; i++)
            //{
            //    ThreadWithHost withHost = new ThreadWithHost(hostList[i]);
            //    int temp = i;
            //    flags[temp]=new AutoResetEvent(false);
            //    Thread t = new Thread(new ParameterizedThreadStart(withHost.ThreadProc));
            //    
            //    t.IsBackground = true;
            //    t.Start(flags[temp]);
            //}
            //WaitHandle.WaitAll(flags);

            foreach (vmModel.Host v in hostList)
            {
                ThreadWithHost withHost=new ThreadWithHost(v);
                Thread t = new Thread(new ThreadStart(withHost.ThreadProc));
                t.Start();
            }
            Thread.Sleep(1000);
            FormVMList_Load(sender, e);
            Thread.Sleep(1000);
            FormVMList_Load(sender, e);
            Thread.Sleep(1000);
            FormVMList_Load(sender, e);
            Thread.Sleep(1000);
            FormVMList_Load(sender, e);
            Thread.Sleep(1000);
            FormVMList_Load(sender, e);
            Thread.Sleep(1000);
            FormVMList_Load(sender, e);
            Thread.Sleep(1000);
            FormVMList_Load(sender, e);
            Thread.Sleep(1000);
            FormVMList_Load(sender, e);

            MessageBox.Show(@"获取完成！");



        }

        private void btFresh_Click(object sender, EventArgs e)
        {
            FormVMList_Load(sender,e);
        }

        private void btVMListClear_Click(object sender, EventArgs e)
        {
            using (vmEntities dbContext = new vmEntities())
            {
                if (dbContext.VMs.Any())
                {
                    dbContext.Delete(dbContext.VMs);
                    dbContext.SaveChanges();
                }
                FormVMList_Load(sender, e);
                MessageBox.Show(@"虚拟列表清空完成！");
            }
        }

        private void btExport_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            
            saveFileDialog1.Filter = @"Excel(*.XLSX)|*.XLSX";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                Workbook workbook = new Workbook(); //工作簿 
                Worksheet sheet = workbook.Worksheets[0]; //工作表 
                Cells cells = sheet.Cells;//单元格 

                //为标题设置样式     
                Style styleTitle = workbook.Styles[workbook.Styles.Add()];//新增样式 
                styleTitle.HorizontalAlignment = TextAlignmentType.Center;//文字居中 
                styleTitle.Font.Name = "微软雅黑";//文字字体 
                styleTitle.Font.Size = 12;//文字大小 
                styleTitle.Font.IsBold = true;//粗体 

                //样式2 
                Style style2 = workbook.Styles[workbook.Styles.Add()];//新增样式 
                style2.HorizontalAlignment = TextAlignmentType.Center;//文字居中 
                style2.Font.Name = "微软雅黑";//文字字体 
                style2.Font.Size = 10;//文字大小 
                style2.Font.IsBold = true;//粗体 
                style2.IsTextWrapped = true;//单元格内容自动换行 
                style2.Borders[BorderType.LeftBorder].LineStyle = CellBorderType.Thin;
                style2.Borders[BorderType.RightBorder].LineStyle = CellBorderType.Thin;
                style2.Borders[BorderType.TopBorder].LineStyle = CellBorderType.Thin;
                style2.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin;

                //样式3 
                Style style3 = workbook.Styles[workbook.Styles.Add()];//新增样式 
                style3.HorizontalAlignment = TextAlignmentType.Center;//文字居中 
                style3.Font.Name = "微软雅黑";//文字字体 
                style3.Font.Size = 8;//文字大小 
                style3.Borders[BorderType.LeftBorder].LineStyle = CellBorderType.Thin;
                style3.Borders[BorderType.RightBorder].LineStyle = CellBorderType.Thin;
                style3.Borders[BorderType.TopBorder].LineStyle = CellBorderType.Thin;
                style3.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin;

                int Colnum = VMdt.Columns.Count;//表格列数 
                int Rownum = VMdt.Rows.Count;//表格行数 

                //生成行1 标题行    
                cells.Merge(0, 0, 1, Colnum);//合并单元格 
                cells[0, 0].PutValue(string.Format("虚拟机清单-{0}", DateTime.Today));//填写内容 
                cells[0, 0].SetStyle(styleTitle);
                cells.SetRowHeight(0, 18);

                //生成行2 列名行 
                for (int i = 0; i < Colnum; i++)
                {
                    cells[1, i].PutValue(VMdt.Columns[i].ColumnName);
                    cells[1, i].SetStyle(style2);
                    cells.SetRowHeight(1, 20);
                }

                //生成数据行 
                for (int i = 0; i < Rownum; i++)
                {
                    for (int k = 0; k < Colnum; k++)
                    {
                        cells[2 + i, k].PutValue(VMdt.Rows[i][k].ToString());
                        cells[2 + i, k].SetStyle(style3);
                    }
                    cells.SetRowHeight(2 + i, 18);
                }

                workbook.Save(saveFileDialog1.FileName);


                //打开保存文件
                MessageBoxButtons buttons = MessageBoxButtons.YesNo;
                DialogResult result;
                result = MessageBox.Show(this,
                    string.Format("导出成功！是否打开文件？"),
                    "导出成功",
                    buttons);
                switch (result)
                {
                    case DialogResult.Yes:
                        {
                            System.Diagnostics.ProcessStartInfo info = new ProcessStartInfo();
                            info.WorkingDirectory = Application.StartupPath;
                            info.FileName = saveFileDialog1.FileName;
                            info.Arguments = "";
                            try
                            {
                                Process.Start(info);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message);
                                throw;
                            }
                        }
                        break;

                    case DialogResult.No:
                        {

                        }
                        break;

                    case DialogResult.Cancel:
                        break;
                }

            }
            
        }
    }

    public class test
    {
        public void MethodA()
        {
            using (vmEntities dbContext=new vmEntities())
            {
                string[] dtStrings = History.OpenDatabases();
                Debug.Assert(dtStrings.Length==0);

                var cate = dbContext.VMs;
                dtStrings = History.OpenDatabases();
                Debug.Assert(dtStrings.Length==1);
            }
        }
    }


    /**
     * ThreadWithState 类里包含了将要执行的任务以及执行任务的方法
     */
    public class ThreadWithHost
    {
        //public event DlgRefresh refresh;

        //要用到的属性，也就是我们要传递的参数
        //private XenAPI.Host host;
        private vmModel.Host myHost;

        //包含参数的构造函数
        public ThreadWithHost(vmModel.Host _myHost)
        {
           // host = _host;
            myHost = _myHost;
        }

        //要丢给线程执行的方法，本处无返回类型就是为了能让ThreadStart来调用
        public void ThreadProc()
        {
            //这里就是要执行的任务,本处只显示一下传入的参数
            using (vmEntities dbContext = new vmEntities()) 
            {
                Session session = new Session(myHost.Ipv4, 80);

                try
                {
                    session.login_with_password(myHost.Username, myHost.Password, API_Version.API_1_3);
                    List<XenRef<XenAPI.VM>> vmRefs = XenAPI.VM.get_all(session);

                    foreach (XenRef<XenAPI.VM> vmRef in vmRefs)
                    {
                        XenAPI.VM vm = XenAPI.VM.get_record(session, vmRef);

                        if (vm.is_a_template.Equals(false) && vm.is_a_snapshot.Equals(false) &&
                        vm.is_control_domain.Equals(false))
                        {
                            string ipv4 = "", ipv6 = "";
                            if (vm.guest_metrics == "OpaqueRef:NULL")
                            { }
                            else
                            {
                                Dictionary<string, string> guestRefs = VM_guest_metrics.get_networks(session, vm.guest_metrics); //获取虚拟机IP地址

                                if (guestRefs.Count > 0)
                                {
                                    foreach (var geMetric in guestRefs)
                                    {
                                        if (geMetric.Key.Contains("ipv6"))
                                        {
                                            ipv6 += "/" + geMetric.Value;
                                        }
                                        else
                                        {
                                            ipv4 += "/" + geMetric.Value;
                                        }
                                    }
                                }
                            }

                            if (!FormVMList.VmIsExists(vm.uuid))
                            {
                                vmModel.VM myVM = new vmModel.VM();
                                myVM.Uuid = vm.uuid;
                                myVM.Cpus = int.Parse(vm.VCPUs_at_startup.ToString());
                                myVM.Vmname = vm.name_label;
                                myVM.Memorys = vm.memory_static_max / 1073741824;
                                myVM.Descr = vm.name_description;
                                myVM.Hostid = myHost.Hostid;
                                myVM.State = vm.power_state.ToString();
                                myVM.Ipv4 = ipv4.Length > 0 ? ipv4.Substring(1) : "";
                                myVM.Ipv6 = ipv6.Length > 0 ? ipv6.Substring(1) : "";

                                dbContext.Add(myVM);
                                dbContext.SaveChanges();
                            }
                            else
                            {
                                IQueryable<vmModel.VM> myVMs = from i in dbContext.VMs
                                                               where i.Uuid == vm.uuid
                                                               select i;
                                if (myVMs.Any())
                                {
                                    vmModel.VM myVM = myVMs.FirstOrDefault();

                                    myVM.Cpus = int.Parse(vm.VCPUs_at_startup.ToString());
                                    myVM.Vmname = vm.name_label;
                                    myVM.Memorys = vm.memory_static_max / 1073741824;
                                    myVM.Descr = vm.name_description;
                                    myVM.Hostid = myHost.Hostid;
                                    myVM.State = vm.power_state.ToString();
                                    myVM.Ipv4 = ipv4.Length > 0 ? ipv4.Substring(1) : "";
                                    myVM.Ipv6 = ipv6.Length > 0 ? ipv6.Substring(1) : "";

                                    dbContext.SaveChanges();
                                }
                            }

                        }

                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    //throw;
                }
            }

        }
    }

}

